package net.chenlin.dp.ids.server.controller;

import net.chenlin.dp.ids.common.constant.IdsConst;
import net.chenlin.dp.ids.common.constant.TicketConst;
import net.chenlin.dp.ids.common.entity.SessionData;
import net.chenlin.dp.ids.common.exception.PassportException;
import net.chenlin.dp.ids.common.util.CommonUtil;
import net.chenlin.dp.ids.common.util.RandomKeyUtil;
import net.chenlin.dp.ids.common.util.TicketUtil;
import net.chenlin.dp.ids.common.util.WebUtil;
import net.chenlin.dp.ids.server.config.PassportServerConfig;
import net.chenlin.dp.ids.server.entity.IdsUserEntity;
import net.chenlin.dp.ids.server.manager.LoginManager;
import net.chenlin.dp.ids.server.service.IdsUserService;
import net.chenlin.dp.ids.server.util.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ids web controller
 * @author zcl<yczclcn@163.com>
 */
@Controller
public class IdsWebController {

    @Autowired
    private PassportServerConfig serverConfig;

    @Autowired
    private IdsUserService userService;

    @Autowired
    private LoginManager loginManager;

    /**
     * passport首页
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model, HttpServletRequest request) {
        String ticket = loginManager.loginCheck(request);
        // 访问首页未登录，直接访问配置欢迎页
        if (CommonUtil.strIsNotEmpty(ticket)) {
            return WebUtil.redirect(serverConfig.getWelcomePage());
        }
        model.addAttribute(IdsConst.TARGET_KEY, serverConfig.getWelcomePage());
        model.addAttribute(IdsConst.REDIRECT_KEY, serverConfig.getWelcomePage() + IdsConst.AUTH_URL);
        return WebUtil.html("login");
    }

    /**
     * 客户端登录页面请求
     * @return
     */
    @RequestMapping(value = IdsConst.LOGIN_URL, method = RequestMethod.GET)
    public String login(Model model, HttpServletRequest request) {
        String service = request.getParameter(IdsConst.REDIRECT_KEY);
        String targetUrl = request.getParameter(IdsConst.TARGET_KEY);
        // 没有跳转地址，则默认欢迎页
        if (CommonUtil.strIsEmpty(service)) {
            service = serverConfig.getWelcomePage();
        }
        String ticket = loginManager.loginCheck(request);
        if (CommonUtil.strIsNotEmpty(ticket)) {
            // 登录成功，回调客户端地址
            String redirectUrl = WebUtil.getAuthUrl(service, ticket, targetUrl);
            return WebUtil.redirect(redirectUrl);
        }
        // 服务端放行校验
        String gateway = request.getParameter(IdsConst.GATEWAY_KEY);
        if (CommonUtil.strIsNotEmpty(gateway) && Boolean.parseBoolean(gateway)) {
            // 放行地址，回调客户端地址
            String redirectUrl = WebUtil.getAuthUrl(service, TicketUtil.getAuthStatusTicket(), targetUrl);
            return WebUtil.redirect(redirectUrl);
        }
        // 未登录，非放行地址，直接跳转登录
        model.addAttribute(IdsConst.REDIRECT_KEY, service);
        model.addAttribute(IdsConst.TARGET_KEY, targetUrl);
        model.addAttribute("errorMsg", request.getParameter("errorMsg"));
        return WebUtil.html("login");
    }

    /**
     * 登录验证
     * @param request
     * @param response
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = IdsConst.LOGIN_URL, method = RequestMethod.POST)
    public String login(HttpServletRequest request, HttpServletResponse response,
                        RedirectAttributes redirectAttributes, String username, String password, String rememberMe) {
        String errorMsg = null;
        IdsUserEntity userEntity = null;
        try {
            if (CommonUtil.strIsEmpty(username.trim())) {
                throw new PassportException("用户名不能为空");
            }
            if (CommonUtil.strIsEmpty(password.trim())) {
                throw  new PassportException("密码不能为空");
            }
            userEntity = userService.getByUserName(username);
            if (userEntity == null) {
                throw new PassportException("当前用户不存在");
            }
            String checkPassword = IdUtil.md5(password, userEntity.getSalt());
            if (!checkPassword.equals(userEntity.getPassword())) {
                throw new PassportException("密码错误");
            }
            if (userEntity.getStatus() == 0) {
                throw new PassportException("账户已被锁定");
            }
        } catch (PassportException e) {
            errorMsg = e.getMessage();
        }
        // 登录失败，重定向登录页面
        if (CommonUtil.strIsNotEmpty(errorMsg)) {
            redirectAttributes.addAttribute("errorMsg", errorMsg);
            redirectAttributes.addAttribute(IdsConst.REDIRECT_KEY, request.getParameter(IdsConst.REDIRECT_KEY));
            redirectAttributes.addAttribute(IdsConst.TARGET_KEY, request.getParameter(IdsConst.TARGET_KEY));
            return WebUtil.redirect(IdsConst.LOGIN_URL);
        }
        // 登录成功
        SessionData sessionData = new SessionData(userEntity.getId(), userEntity.getUsername(),
                userEntity.getStatus(), IdsConst.LOGIN_TYPE_WEB);
        sessionData.setIsLogin(1);
        // Remember me
        boolean isRemember = false;
        if (CommonUtil.strIsNotEmpty(rememberMe) && IdsConst.REMEMBER_ON.equals(rememberMe)) {
            isRemember = true;
        }
        sessionData.setRememberMe(isRemember);
        // 登录
        String sessionId = loginManager.login(response, sessionData);
        // 更新最近登录时间
        userService.updateUserLastLoginTime(userEntity.getId());
        // 重定向地址，如为空，则跳转服务端配置欢迎页
        String serviceUrl = request.getParameter(IdsConst.REDIRECT_KEY);
        if (CommonUtil.strIsEmpty(serviceUrl)) {
            serviceUrl = serverConfig.getWelcomePage();
        }
        // 拼接重定向地址
        String redirectUrl = WebUtil.getAuthUrl(serviceUrl, sessionId, request.getParameter(IdsConst.TARGET_KEY));
        return WebUtil.redirect(redirectUrl);
    }

    /**
     * 登出
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(IdsConst.LOGOUT_URL)
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        loginManager.logout(request, response);
        String redirectUrl = request.getParameter(IdsConst.REDIRECT_KEY);
        return WebUtil.redirect(redirectUrl);
    }

}
